/*
 * Copyright TLR Team, Inc. All Rights Reserved.
 */
package com.tlr.device.service;

import com.tfb.rong.Device;
import com.tfb.service.utility.AppConst;
import com.tfb.service.utility.JsonUtil;
import com.tfb.service.utility.HttpUtil;
import com.tlr.device.model.AirBox;
import com.tlr.device.rest.AppContext;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.codehaus.jackson.JsonNode;
import org.springframework.util.StringUtils;

public class AirMeasureDevice implements AppConst {

    private static final Log log = LogFactory.getLog(AirMeasureDevice.class);

    private String getDeviceListUrl() {
        return String.format(AIR_MEASURE_DEVICE_LIST, AppContext.getAirMeasureDeviceToken());
    }

    private String getDeviceDataUrl(String strMac, String queryType) {
        return String.format(AIR_MEASURE_DEVICE_LIST_DATA, AppContext.getAirMeasureDeviceToken(), strMac, queryType);
    }

    private String getDeviceDayHistoryUrl(String strMac, String queryType) {
        return String.format(AIR_MEASURE_DEVICE_HISTORY_DAY, AppContext.getAirMeasureDeviceToken(), strMac, queryType);
    }

    private String getDeviceHourHistoryUrl(String strMac, String queryType) {
        return String.format(AIR_MEASURE_DEVICE_HISTORY_HOUR, AppContext.getAirMeasureDeviceToken(), strMac, queryType);
    }

    public JsonNode getDevcieListJson() throws IOException {
        try (CloseableHttpClient httpClient = HttpUtil.createHttpClient()) {
            String devceListUrl = getDeviceListUrl();
            HttpGet httpGet = new HttpGet(devceListUrl);
            try (CloseableHttpResponse deviceListResp = httpClient.execute(httpGet)) {
                String devceListJsonStr = EntityUtils.toString(deviceListResp.getEntity(), JsonUtil.UTF8);
                JsonNode deviceListJson = JsonUtil.createJson(devceListJsonStr);
                return deviceListJson;
            }
        }
    }

    public JsonNode getDeviceDataJson(String deviceMAC, String queryType) throws IOException {
        try (CloseableHttpClient httpClient = HttpUtil.createHttpClient()) {
            String deviceDataUrl = getDeviceDataUrl(deviceMAC, queryType);
            HttpGet httpGet = new HttpGet(deviceDataUrl);
            try (CloseableHttpResponse deviceDataResp = httpClient.execute(httpGet)) {
                String deviceDataJsonStr = EntityUtils.toString(deviceDataResp.getEntity(), JsonUtil.UTF8);
                JsonNode deviceDataJson = JsonUtil.createJson(deviceDataJsonStr);
                return deviceDataJson;
            }
        }
    }

    public JsonNode getDeviceDayHistoryDataJson(String deviceMAC, String queryType) throws IOException {
        try (CloseableHttpClient httpClient = HttpUtil.createHttpClient()) {
            String deviceDayHistoryUrl = getDeviceDayHistoryUrl(deviceMAC, queryType);
            HttpGet httpGet = new HttpGet(deviceDayHistoryUrl);
            try (CloseableHttpResponse deviceDayHistoryResp = httpClient.execute(httpGet)) {
                String deviceDayHistoryJsonStr = EntityUtils.toString(deviceDayHistoryResp.getEntity(), JsonUtil.UTF8);
                JsonNode deviceDataJson = JsonUtil.createJson(deviceDayHistoryJsonStr);
                return deviceDataJson;
            }
        }
    }

    public JsonNode getDeviceHourHistoryDataJson(String deviceMAC, String queryType) throws IOException {
        try (CloseableHttpClient httpClient = HttpUtil.createHttpClient()) {
            String deviceHourHistoryUrl = getDeviceHourHistoryUrl(deviceMAC, queryType);
            HttpGet httpGet = new HttpGet(deviceHourHistoryUrl);
            try (CloseableHttpResponse deviceHourHistoryResp = httpClient.execute(httpGet)) {
                String deviceHourHistoryJsonStr = EntityUtils.toString(deviceHourHistoryResp.getEntity(), JsonUtil.UTF8);
                JsonNode deviceDataJson = JsonUtil.createJson(deviceHourHistoryJsonStr);
                return deviceDataJson;
            }
        }
    }

    public List<AirBox> getDeviceListLastData() throws IOException {
        return getDeviceListLastData(null);
    }

    public List<AirBox> getDeviceListLastData(Map<String, Device> validMacList) throws IOException {
        JsonNode deviceListJson = getDevcieListJson();
        JsonNode deviceListJsonArray = deviceListJson.get("设备列表");
        Iterator<JsonNode> deviceListIt = deviceListJsonArray.getElements();
        ArrayList<AirBox> deviceList = new ArrayList<>();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        Calendar validCalendar = Calendar.getInstance();
        validCalendar.add(Calendar.DAY_OF_MONTH, -1);
        Date validDate = validCalendar.getTime();
        while (deviceListIt.hasNext()) {
            JsonNode deviceNode = deviceListIt.next();
            String deviceMAC = deviceNode.get("设备地址").getTextValue();
            Device device = validMacList != null ? validMacList.get(deviceMAC) : null;
            if (validMacList != null && device == null) {
                continue;
            }
            String deviceCity = deviceNode.get("城市").getTextValue();
            String deviceLongitude = deviceNode.get("腾讯经度").getTextValue();
            String deviceLatitude = deviceNode.get("腾讯纬度").getTextValue();
            // TODO **** workaround for offset from device *****
            deviceLongitude = Double.toString(Double.parseDouble(deviceLongitude) - 0.002);
            deviceLatitude = Double.toString(Double.parseDouble(deviceLatitude) + 0.005);
            JsonNode deviceDataJson = getDeviceDataJson(deviceMAC, "PM2.5");
            deviceDataJson = deviceDataJson.get("设备数据").get(0);
            AirBox box = new AirBox();
            box.setDevice_city(deviceCity);
            box.setDevice_mac(deviceMAC);
            box.setDevice_lang(StringUtils.isEmpty(device.getDevicelang()) ? deviceLatitude : device.getDevicelang());
            box.setDevice_lati(StringUtils.isEmpty(device.getDevicelati()) ? deviceLongitude : device.getDevicelati());
            box.setData_type("PM2.5");
            box.setStorage_id(device.getDeviceid());
            box.setNick_name(device.getBindNickName());
            JsonNode value = deviceDataJson.get("检测PM2.5");
            if (value.isInt()) {
                box.setPm25_measure(value.getIntValue());
            } else {
                box.setPm25_measure(Integer.parseInt(value.getTextValue()));
            }
            value = deviceDataJson.get("室外PM2.5");
            if (value.isInt()) {
                box.setPm25_outdoor(value.getIntValue());
            } else {
                box.setPm25_outdoor(Integer.parseInt(value.getTextValue()));
            }
            box.setLast_time(deviceDataJson.get("上传时间").getTextValue());
            try {
                Date lastDate = df.parse(box.getLast_time());
                if (lastDate.after(validDate)) {
                    box.setExpired(false);
                } else {
                    box.setExpired(true);
                    log.error("Device '" + box.getDevice_mac() + "' data is expired, its last time is: " + box.getLast_time());
                }
                deviceList.add(box);
            } catch (ParseException ex) {
                log.error(ex.fillInStackTrace());
            }
        }
        return deviceList;
    }

    public List<AirBox> getDeviceDayHistoryData(String strMac, String dataType) throws IOException {
        ArrayList<AirBox> deviceList = new ArrayList<>();
        JsonNode deviceDayHistoryDataJson = getDeviceDayHistoryDataJson(strMac, dataType);
        Iterator<JsonNode> historyIt = deviceDayHistoryDataJson.get("设备数据").iterator();
        while (historyIt.hasNext()) {
            JsonNode dayJson = historyIt.next();
            AirBox box = new AirBox();
            box.setDevice_mac(strMac);
            box.setData_type(dataType);
            box.setPm25_measure(dayJson.get("检测PM2.5").getIntValue());
            box.setPm25_outdoor(dayJson.get("室外PM2.5").getIntValue());
            box.setHistory_year(dayJson.get("年份").getIntValue());
            box.setHistory_month(dayJson.get("月份").getIntValue());
            box.setHistory_day(dayJson.get("日").getIntValue());
            deviceList.add(box);
        }
        return deviceList;
    }

    public List<AirBox> getDeviceHourHistoryData(String strMac, String dataType) throws IOException {
        ArrayList<AirBox> deviceList = new ArrayList<>();
        JsonNode deviceHourHistoryDataJson = getDeviceHourHistoryDataJson(strMac, dataType);
        Iterator<JsonNode> historyIt = deviceHourHistoryDataJson.get("设备数据").iterator();
        while (historyIt.hasNext()) {
            JsonNode hourJson = historyIt.next();
            AirBox box = new AirBox();
            box.setDevice_mac(strMac);
            box.setData_type(dataType);
            box.setPm25_measure(hourJson.get("检测PM2.5").getIntValue());
            box.setPm25_outdoor(hourJson.get("室外PM2.5").getIntValue());
            box.setHistory_year(hourJson.get("年份").getIntValue());
            box.setHistory_month(hourJson.get("月份").getIntValue());
            box.setHistory_day(hourJson.get("日").getIntValue());
            box.setHistory_hour(hourJson.get("小时").getIntValue());
            deviceList.add(box);
        }
        return deviceList;
    }
}
